/*-------------------------------------------------------------------------
 - Copyright (c) 2024-2025 [XD-AMCC TEAM]
 - [XD-AMCC] is licensed under Mulan PSL v2.
 - You can use this software according to the terms and conditions of the Mulan PSL v2.
 - You may obtain a copy of Mulan PSL v2 at:
 -          http://license.coscl.org.cn/MulanPSL2
 - THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
 - OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 - TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 - See the Mulan PSL v2 for more details.
 ------------------------------------------------------------------------*/


/**
 * @file
 * @brief Interface of class token and token-kinds.
 *
 * @author  WXQ#XDU
 * @date    2024.11
 */

#pragma once

#ifndef AMCC_TOKENS_H
#define AMCC_TOKENS_H

#include <stdbool.h>
#include <stdlib.h>  // for malloc, free

#include "amcc_config.h"
#include "amcc_string.h"

AMCC_DECL_BEGIN


/**
 * @brief Definition of token kinds, aka token names.
 */
typedef enum TokenKind {
    TK_UNSUPPORT = 1,
    TK_ERROR        , //!< Bad input
    TK_EOF          , //!< End-Of-File
    TK_EPSILON      , //!< placeholder for EPSILON
    TK_INT_LITERAL  , //!< common name of all integer literals, and
                      //!< backend MUST ONLY use this value

    // In following file, four boundary name are defined as:
    // TK_KW_MIN__   < any-key-word  < TK_KW_MAX__
    // TK_TYPE_MIN__ < any-base-type < TK_TYPE_MAX__
#include "../meta/kw_token_kinds.inc"  //generated by my tool

    TK_DFA_MIN__ , // just a boundary, follow items come from DFA
#include "../meta/dfa_token_kinds.inc"  //generated by my tool
    TK_DFA_MAX__ , // just a boundary, above items come from DFA


    TK_UNKNOWN       //!< tag for last item, the max code
} EnumTokenKind;

/**
 * @brief Get the name string of the token kind.
 * 
 * @param tokKind     the token kind
 * @return return the name of the token kind or
 *         "UNKNOWN(...)" for unknown kind.
 */
extern const char *  token_nameOfKind(EnumTokenKind tokKind);

/**
 * @brief Get a sample string of the token kind.
 * @param tokKind  the token kind
 * @return return a sample string of token kind or
 *         "&lt;UNKNOWN&gt;" for unknown kind.
 */
extern const char *  token_sampleOfKind(EnumTokenKind tokKind);

/**
 * @brief The position of a token, a char or a string in input file.
 */
typedef struct position {
    const char *  filePath; //!< path of input file
    int line;               //!< line number that starts from 1
    int column;             //!< column number that starts from 1
} t_position, * t_position_ptr;

// type alias of token's integer-value attribute
typedef  int token_intvalue_t;

#define AMCC_INT2STR_FMTSTR "u"  // postfix of format-spec for printf
#define AMCC_INTMAX_LITERAL 0x7FFFFFFFUL // max value of 'int' literal


struct token_body;

/**
 * @brief Class token.
 *
 * A token is an instance of a terminal of grammar.
 */
typedef struct token {
    struct token_body * tokenBody;  //!< basic data of a token
    t_position      pos;            //!< start position of this token
} t_token, *  t_token_ptr;


// -----------------------------------------------------------------------
/// @name API of class token
/// @{


/**
 * @brief Get the kind of the token.
 * @param pThis  pointer to this token
 * @return Return the kind of this token
 */
extern EnumTokenKind token_get_kind(t_token_ptr pThis);

// Whether this token is a built-in type name
extern bool token_is_type(t_token_ptr pThis);

// Whether this token is the EOF
extern bool token_is_eof(t_token_ptr pThis);

/**
 * @brief Get the kind name of the token.
 * @param pThis  pointer to this token
 * @return Return the kind name of this token
 */
extern const char * token_get_kindName(t_token_ptr pThis);

/**
 * @brief Get the position of the token in input file.
 * @param pThis  pointer to this token
 * @return Return the position of this token
 */
extern t_position_ptr token_get_position(t_token_ptr pThis);


/**
 * @brief Get the length of token text.
 * @param pThis  pointer to this token
 * @return Return the length of token text from input file.
*/
extern int token_get_length(t_token_ptr pThis);

/**
 * @brief Get the text (lexeme) of this token.
 * @param pThis  pointer to this token
 * @return A pointer to constant C-string of this token.
 */
extern const char* token_get_text(t_token_ptr pThis);


/**
 * @brief Get an integer semantic-value of this token.
 * @param pThis  pointer to this token
 * @return Return an integer number if this token can be treated as number.
 * @return Return the token kind for other tokens.
 */
extern token_intvalue_t  token_get_intValue(t_token_ptr pThis);

/**
 * @brief Get a double that represents the semantic-value of this token.
 * @param pThis  pointer to this token
 * @return Return a real number  if this token can be treated as number.
 * @return Return the token kind for other tokens.
 */
extern double token_get_doubleValue(t_token_ptr pThis);

/**
 * @brief Get a string that represents the semantic-value of this token.
 * @param pThis  pointer to this token
 * @return Currently, return the raw input text of this token.
 */
extern const char * token_get_stringValue(t_token_ptr pThis);


/// @}
// -----------------------------------------------------------------------


AMCC_DECL_END

#endif // #ifndef AMCC_TOKENS_H
